// dispathprocess.cpp
// Created by fyniny on 12/23/18.
//
#include <ctime>
#include "dispatchprocess.h"
#ifdef DEBUG
auto seed = (unsigned int) 0;//((unsigned)time(0));//
#else
auto seed = ((unsigned int)time(nullptr));
#endif
void DispathProcess::addProcess(int id, Base* base) {
    assert(m_process[id] == nullptr);
    m_process[id] = base;
}
DispathProcess::DispathProcess() {
    srand(seed);
}
DispathProcess::~DispathProcess() = default;
Base &DispathProcess::dispath() {
    int id = -1;
    while (id == -1) {
        id = rand() % 100;
        id = Dispath(id);
    }
    Base *tmp = getInstance(id);
    assert(tmp != nullptr);
    return *tmp;
}
void DispathProcess::run() {
    // 所有进程全部退出，退成次循环，程序结束运行
    while (!isAllDied()) {
        Base &current = dispath();
        // 处理死亡进程
        if (
                current.getProcessStatus() == PROCESS_RESULT
                ) {
            std::cout << "\n------------------call process " << current.getProcessID() << " but it died------------------\n";
            //assert(false);
            continue;
        }


        // 进程处于等待状态
        if (
                current.getProcessStatus() == PROCESS_WAIT_FULL_OUTPUT_BLOCK
                ||
                current.getProcessStatus() == PROCESS_WAIT_EMPTY_OUTPUT_BLOCK
                ) {
            std::cout << "\n------------------call process " << current.getProcessID()
                 << " but it block------------------\n";
            continue;
        }

        std::cout << "\n---start---------call process " << current.getProcessID() << " and it runs------------------\n";
        // 执行
        current.run(this);
        switch (current.getProcessStatus()) {
            case PROCESS_WAIT_EMPTY_OUTPUT_BLOCK:
            case PROCESS_WAIT_FULL_OUTPUT_BLOCK:
                std::cout << "\n---end---------call process " << current.getProcessID() << " and it block------------------\n";
                break;
            case PROCESS_RESULT:
                std::cout << "\n---end---------call process " << current.getProcessID() << " and it died------------------\n";
                break;
            case PROCESS_EXECUTABLE:
                std::cout << "\n---end---------call process " << current.getProcessID() << " and it executable------------------\n";
                break;
            default:
                std::cout << "\n---end---------call process " << current.getProcessID() << " and it runs error------------------\n";
        }

    }
}
bool DispathProcess::isAllDied() {
//    防止因为key值创建了空的value
    for (auto ite : m_process) {
        if (ite.second == nullptr) {
            continue;
        }
        if (ite.second->getProcessStatus() != PROCESS_RESULT) {
            return false;
        }
    }
    return true;
}
Base *DispathProcess::getInstance(int id) {
    for (auto ins:this->m_process) {
        if (ins.second->getProcessID() == id){
            return ins.second;
        }
    }
    return nullptr;
}